package com.ly.heart.service.king.base;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.google.gson.Gson;
import com.kingdee.bos.webapi.entity.IdentifyInfo;
import com.kingdee.bos.webapi.entity.RepoRet;
import com.kingdee.bos.webapi.sdk.K3CloudApi;
import com.ly.common.exception.CustomException;
import com.ly.common.utils.DateUtils;
import com.ly.common.utils.SecurityUtils;
import com.ly.common.utils.erp.KingConstUtil;
import com.ly.common.utils.erp.SnowflakeIdWorker;
import com.ly.heart.domain.*;
import com.ly.heart.domain.king.BaseChildBo;
import com.ly.heart.domain.king.base.customer.CustomerAddressBo;
import com.ly.heart.domain.king.base.customer.CustomerBankBo;
import com.ly.heart.domain.king.base.customer.CustomerBo;
import com.ly.heart.domain.king.base.customer.CustomerContactsBo;
import com.ly.heart.domain.request.KingBaseSingleRequest;
import com.ly.heart.domain.response.KingBaseResponse;
import com.ly.heart.domain.response.KingBaseResponseError;
import com.ly.heart.domain.response.KingBaseResponseSuccessEntity;
import com.ly.heart.service.*;
import com.ly.heart.util.CurrentUserUtil;
import com.ly.heart.util.KingCommonUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class CustomerPushService {

    @Resource
    private IKingOrgService iKingOrgService;
    @Resource
    private ICustomerService iCustomerService;
    @Resource
    private IContactsInfoService iContactsInfoService;
    @Resource
    private IBankInfoService iBankInfoService;
    @Resource
    private IErpAddressService addressService;

    @ApiOperation ( "同步拉取客户到金蝶" )
    @RequestMapping ( "pull" )
    public void pull () {
        KingOrgEntity orgEntity = iKingOrgService.getOne ( new LambdaQueryWrapper<KingOrgEntity> ().eq ( KingOrgEntity :: getOrgId, CurrentUserUtil.getCompanyId () ).eq ( KingOrgEntity :: getIsDisabled, false ) );
        if ( orgEntity == null ) {
            throw new CustomException ( "请先至系统管理中配置金蝶账套！" );
        }
        IdentifyInfo identifyInfo = KingCommonUtil.getIdentifyInfo ( orgEntity );
        K3CloudApi client = new K3CloudApi ( identifyInfo );
        /**
         * 编码，名称，
         */
        String jsonData = "{\"FormId\":\"" + KingConstUtil.BD_Customer + "\",\"FieldKeys\":\"FNumber,FName\",\"FilterString\":[],\"OrderString\":\"\",\"TopRowCount\":0,\"StartRow\":0,\"Limit\":2000,\"SubSystemId\":\"\"}";

        List<List<Object>> lists = null;
        try {
            lists = client.executeBillQuery ( jsonData );
            for ( int i = 0; i < lists.size (); i++ ) {
                List<Object> objects = lists.get ( i );
                //根据code查询是否已存在该结算方式
                String bizCode = ( String ) objects.get ( 0 );
                CustomerEntity one = iCustomerService.getOne ( new LambdaQueryWrapper<CustomerEntity> ().eq ( CustomerEntity :: getCustomerCode, bizCode ) );
                if ( one == null ) {
                    one = new CustomerEntity ();
                    one.setId ( SnowflakeIdWorker.getInstance ().nextStringId () );
                    one.setCustomerCode ( String.valueOf ( objects.get ( 0 ) ) );
                    one.setCustomerName ( String.valueOf ( objects.get ( 1 ) ) );
                    one.setCreateId ( SecurityUtils.getLoginUser ().getUser ().getUserId () );
                    one.setCreateTime ( DateUtils.getNowDate () );
                    iCustomerService.save ( one );
                }
            }
        } catch ( Exception e ) {
            e.printStackTrace ();
        }
    }


    @ApiOperation ( "同步发送客户到金蝶" )
    @RequestMapping ( "push" )
    public void push ( String id ) {
        KingOrgEntity orgEntity = iKingOrgService.getOne ( new LambdaQueryWrapper<KingOrgEntity> ().eq ( KingOrgEntity :: getOrgId, CurrentUserUtil.getCompanyId () ).eq ( KingOrgEntity :: getIsDisabled, false ) );
        if ( orgEntity == null ) {
            throw new CustomException ( "请先至系统管理中配置金蝶账套！" );
        }
        IdentifyInfo identifyInfo = KingCommonUtil.getIdentifyInfo ( orgEntity );
        K3CloudApi client = new K3CloudApi ( identifyInfo );
        CustomerEntity one = iCustomerService.getOne ( new LambdaQueryWrapper<CustomerEntity> ().eq ( CustomerEntity :: getId, id ).eq ( CustomerEntity :: getIsSend, KingConstUtil.KING_DATA_IS_SEND_NO ) );
        if ( one == null ) {
            throw new CustomException ( "该客户已推，无需重复推送！" );
        }
        CustomerBo bo = assembleCustomer ( one );
        try {
            save ( bo, client );
            submit ( bo, client );
            audit ( bo, client );
            updateSendSuccess ( one.getId () );
        } catch ( Exception e ) {
            e.printStackTrace ();
            throw new CustomException ( "客户推送失败，请稍后重试！" );
        }
    }


    private void save ( CustomerBo bo, K3CloudApi client ) throws Exception {
        KingBaseSingleRequest singleRequest = new KingBaseSingleRequest ();
        singleRequest.setModel ( bo );
        String s = JSONObject.toJSONString ( singleRequest );
        log.info ( "客户转JSON->{}", s );
        String resultJson = client.save ( KingConstUtil.BD_Customer, s );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () ) {
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "客户-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.info ( "{} 推送成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "客户-推送失败：【" + sb + "】" );
        }
    }


    /**
     * 提交采购开票(应付单)到金蝶
     *
     * @param bo
     * @param client
     */
    private void submit ( CustomerBo bo, K3CloudApi client ) throws Exception {
        List<String> strings = new ArrayList<> ();
        strings.add ( bo.getFNumber () );
        bo.setNumbers ( strings );
        String jsonData = JSON.toJSONString ( bo );
        String resultJson = client.submit ( KingConstUtil.BD_Customer, jsonData );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () ) {
            //提交成功
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "客户-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.error ( "{} 提交成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "客户提交失败：【" + sb + "】" );
        }
    }

    /**
     * 审核应付单
     *
     * @param bo
     * @param client
     */
    private void audit ( CustomerBo bo, K3CloudApi client ) throws Exception {
        List<String> strings = new ArrayList<> ();
        strings.add ( bo.getFNumber () );
        bo.setNumbers ( strings );
        String jsonData = JSON.toJSONString ( bo );
        String resultJson = client.audit ( KingConstUtil.BD_Customer, jsonData );
        Gson gson = new Gson ();
        //对返回结果进行解析和校验
        RepoRet repoRet = gson.fromJson ( resultJson, RepoRet.class );
        KingBaseResponse baseResponse = JSONObject.parseObject ( gson.toJson ( repoRet.getResult ().getResponseStatus () ), KingBaseResponse.class );
        StringBuilder sb = new StringBuilder ();
        if ( baseResponse.getIsSuccess () ) {
            //提交成功
            List<KingBaseResponseSuccessEntity> successEntities = baseResponse.getSuccessEntitys ();
            sb.append ( "客户-编码为：【" );
            successEntities.forEach ( success -> {
                sb.append ( success.getNumber () ).append ( ";" );
            } );
            sb.append ( "】" );
            log.error ( "{} 审核成功", sb );
        } else {
            List<KingBaseResponseError> errors = baseResponse.getErrors ();
            errors.forEach ( err -> {
                sb.append ( err.getMessage () ).append ( ";" );
            } );
            throw new RuntimeException ( "客户审核失败：【" + sb + "】" );
        }
    }

    private void updateSendSuccess ( String id ) {
        boolean update = iCustomerService.update ( new LambdaUpdateWrapper<CustomerEntity> ().
                set ( CustomerEntity :: getIsSend, KingConstUtil.KING_DATA_IS_SEND_YES ).
                eq ( CustomerEntity :: getId, id ) );
        if ( ! update ) {
            throw new CustomException ( "修改推送金蝶状态失败！" );
        }
    }


    private CustomerBo assembleCustomer ( CustomerEntity customerEntity ) {
        CustomerBo bo = new CustomerBo ();
        bo.setFName ( customerEntity.getCustomerName () );
        bo.setFNumber ( customerEntity.getCustomerCode () );
        BaseChildBo base = new BaseChildBo ().setFNumber ( "100" );
        bo.setFCreateOrgId ( base );
        bo.setFINVOICETITLE ( customerEntity.getInvoiceHeader () );
        base = new BaseChildBo ().setFNumber ( customerEntity.getCustomerType () );
        bo.setFCustTypeId ( base );
        base = new BaseChildBo ().setFNumber ( customerEntity.getCompanySize () );
        bo.setFCompanyScale ( base );
        base = new BaseChildBo ().setFNumber ( customerEntity.getCompanyType () );
        bo.setFCompanyClassify ( base );
        base = new BaseChildBo ().setFNumber ( customerEntity.getCompanyNature () );
        bo.setFCompanyNature ( base );
        bo.setFADDRESS ( customerEntity.getAddress () );
        bo.setFZIP ( customerEntity.getPostCode () );
        bo.setFWEBSITE ( customerEntity.getCompanyUrl () );
        bo.setFTEL ( customerEntity.getTelPhone () );
        bo.setFFAX ( customerEntity.getFacsimile () );
        bo.setFTAXREGISTERCODE ( customerEntity.getTaxId () );
        bo.setFINVOICEBANKNAME ( customerEntity.getOpenBank () );
        bo.setFINVOICEBANKACCOUNT ( customerEntity.getBankAccount () );
        bo.setFINVOICETEL ( customerEntity.getInvoiceHotline () );
        bo.setFINVOICEADDRESS ( customerEntity.getInvoiceAddress () );
        bo.setFSOCIALCRECODE ( customerEntity.getUnifiedCode () );

        //客户联系人
        List<CustomerContactsBo> customerContactsBos = assembleCustomerContact ( customerEntity.getId () );
        bo.setFT_BD_CUSTLOCATION ( customerContactsBos );

        //客户银行
        List<CustomerBankBo> customerBankBos = assembleCustomerBank ( customerEntity.getId () );
        bo.setFT_BD_CUSTBANK ( customerBankBos );

        List<CustomerAddressBo> customerAddressBos = assembleCustomerAddress ( customerEntity.getId () );
        bo.setFT_BD_CUSTCONTACT ( customerAddressBos );

        return bo;
    }


    private List<CustomerContactsBo> assembleCustomerContact ( String customerId ) {
        List<CustomerContactsBo> customerContactsBos = new ArrayList<> ();
        List<ContactsEntity> list = iContactsInfoService.list ( new LambdaQueryWrapper<ContactsEntity> ().eq ( ContactsEntity :: getCustomerId, customerId ) );
        list.forEach ( contact -> {
            CustomerContactsBo b = new CustomerContactsBo ();
            b.setFCONTACT ( contact.getName () );
            customerContactsBos.add ( b );
        } );
        return customerContactsBos;
    }

    private List<CustomerBankBo> assembleCustomerBank ( String customerId ) {
        List<CustomerBankBo> customerBankBos = new ArrayList<> ();
        List<BankEntity> list = iBankInfoService.list ( new LambdaQueryWrapper<BankEntity> ().eq ( BankEntity :: getRelationId, customerId ) );
        list.forEach ( bank -> {
            CustomerBankBo b = new CustomerBankBo ();
            b.setFOPENBANKNAME ( bank.getBankName () );
            b.setFACCOUNTNAME ( bank.getAccountName () );
            b.setFBANKCODE ( bank.getBankAccount () );
            b.setFOpenAddressRec ( bank.getOpenBankAddress () );
            customerBankBos.add ( b );
        } );
        return customerBankBos;
    }

    private List<CustomerAddressBo> assembleCustomerAddress ( String customerId ) {
        List<CustomerAddressBo> customerAddressBos = new ArrayList<> ();
        List<ErpAddress> list = addressService.list ( new LambdaQueryWrapper<ErpAddress> ().eq ( ErpAddress :: getRelationId, customerId ) );
        list.forEach ( address -> {
            CustomerAddressBo b = new CustomerAddressBo ();
            b.setFNUMBER1 ( address.getAddressCode () );
            b.setFNAME1 ( address.getAddressName () );
            b.setFEMail ( address.getEmail () );
            b.setFMOBILE ( address.getPhone () );
            customerAddressBos.add ( b );
        } );
        return customerAddressBos;
    }


}
